<?php


namespace App\Services\Java;


use App\Services\Base;
use D1M\Common\Exceptions\BusinessException;
use App\Exceptions\JavaApiException;
use D1M\Common\Helpers\Result;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;

class ApiService extends Base
{


    /**
     * Java Api 签名
     *
     */
    public function sign(string $data)
    {
        //处理业务参数
        //$data = $this->dealData($data);

        // 在header中增加公共参数SHOP_ID，提供给java使用
        Log::info('转发java接口请求头是：'.json_encode($_SERVER));
        $shopId = empty($_SERVER['HTTP_SHOP_ID']) ? null : $_SERVER['HTTP_SHOP_ID'];

        $nonceStr = $this->random(10);
        $timestamp = $this->timestamp();

        $params = [
            'SecretId'  =>env("JAVA_API_SECRET_ID"),
            'Nonce'     => $nonceStr,
            'Timestamp'    => $timestamp,
            'Data'          => $data,
        ];
        if($data==='[]')unset($params['Data']);
        ksort($params);


        $keyValues = [];
        foreach ($params as $key => $value) {
            $keyValues[] = "{$key}=$value";
        }
        $str = implode('&', $keyValues).'&SecretKey='.env("JAVA_API_SECRET_KEY");
        Log::info('sign str：'.$str);
        $sign = strtoupper(hash_hmac('sha256',$str,env("JAVA_API_SECRET_KEY")));
        return [
            'SecretId'    => env("JAVA_API_SECRET_ID"),
            'Nonce' => $nonceStr,
            'Timestamp' => $timestamp,
            'Signature'      => $sign,
            'ShopId'        => $shopId,
            //'data'      =>$data
        ];
    }

    public function testException($a)
    {
        Redis::set('name','shanshan111');
        Redis::expire('name',7200);
        if($a>0){
            throw new \App\Exceptions\JavaApiException('aaa',11111);
        }
    }

    public function dealData(array $data)
    {
        $key = env("JAVA_API_SECRET_KEY");
        foreach ($data as $k=>$v){
            //if(empty($v)){
            if($v==='' || $v===null){
                unset($data[$k]);
            }else{
                $data[$k] = $this->arrayData($v,$key);
                if(empty($data[$k]))unset($data[$k]);
            }
        }
        ksort($data);
        return json_encode($data);
    }

    private function arrayData($v,$key)
    {
        if(is_array($v)){
            foreach ($v as $x=>$y)
            {
                //if(empty($y)){
                if($y==='' || $y===null){
                    unset($v[$x]);
                }else{
                    $v[$x] = $this->arrayData($y,$key);
                }
                //$v[$x] = $this->arrayData($y,$key);
            }
            ksort($v);
        }else{
            $v = $this->encrypt($v,$key);
        }

        return $v;
    }

    /**
     * @return string
     */
    public function token()
    {
        $key = 'pawhub_java_api_token';
        $token = Redis::get($key);
        if($token){
            return $token;
        }
        return $this->getJavaToken();
    }

    public function getJavaToken()
    {
        $url = env("JAVA_API_BASE_URL").'/auth/open/login/getToken';
        $res = Http::timeout(3)->post($url, ['secretId'=>env('JAVA_API_SECRET_ID')]);
        $res->throw();
        $result = $res->json();
        if($result['error']){
            Log::error($result['error']['message']);
            throw new JavaApiException($result['error']['message'],$result['error']['code']);
        }
        //添加到redis
        $accessToken = $result['data']['accessToken'];
        if($accessToken){
            $key = 'pawhub_java_api_token';
            Redis::set($key,$accessToken);
            Redis::expire($key,7200);
        }

        return $accessToken;
    }

    /**
     * @return string
     */
    public function requestJava($url, array $data,$method='get')
    {
        Log::info('请求java参数：'.json_encode($data));
        //数据加密
        $data = stripslashes($this->dealData($data));
        //dump($data);die;
        //获取token
        $token = $this->token();
        //获取签名
        $sign = $this->sign($data);

        $url = env("JAVA_API_BASE_URL").$url;
        Log::info('请求java的地址：'.$url);

        $params = ['data'=>json_decode($data,true)];

        $response = Http::timeout(5)
            ->withToken($token)
            ->withHeaders($sign)
            ->$method($url, $params);
        $response->throw();

        $result = $response->json();

        Log::info('请求参数：'.json_encode($params));
        Log::info('sign：'.json_encode($sign));
        Log::info('token：'.$token);
        Log::info('url:'.$url.',请求方法：'.$method.',请求结果：'.json_encode($result));


        if (isset($result['error'])) {
            //100037token失效重新获取token！！！
            if($result['error']['code']==100037){
                $this->getJavaToken();
            }

            $msg = $url."发生错误，错误码："
                . "{$result['error']['code']}，错误消息：{$result['error']['message']}";
            Log::error($msg);
            throw new JavaApiException($result['error']['message'],$result['error']['code']);

        }

        return $result['data'];
    }

    public function timestamp()
    {
        $time = explode (" ", microtime () );
        $micro = explode(".",$time [0]);
        $micro = substr($micro[1],0,3);
        return $time [1] . $micro;
    }





}